/*
 * Copyright (c) 2021 KaiHong Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <hi_types_base.h>
#include "hos_init.h"
#include "cmsis_os2.h"
#include "wifi_device.h"
#include "lwip/netifapi.h"
#include "lwip/api_shell.h"
#include "softap.h"
#include "savewifi.h"
#include "sta.h"
#define macAddress_Num 32
#define Audio_buff_Num 50
#define Audio_buff_data_Lenth 1024
#define Delay_Lenth 20
#define Send_Lenth 2
#define Audio_flag 2
hi_u8 audio_flag;
const char* MY_ip = "106.12.200.27";
unsigned short my_port = 1122;
char request[] = "sb";
char response[128] = "";
hi_u8 audio_flag;
hi_u8 get_buff1[50][1024];
static void PrintLinkedInfo(WifiLinkedInfo* info)
{
    if (!info) return;
    static char macAddress[macAddress_Num] = {0};
    return;
}
static int g_connected = 0;
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
{
    if (!info) return;

    printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
    PrintLinkedInfo(info);

    if (state == WIFI_STATE_AVALIABLE) {
        g_connected = 1;
    } else {
        g_connected = 0;
    }
}
static void OnWifiScanStateChanged(int state, int size)
{
    printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
}
void TcpClientTest(const char* host, unsigned short port)
{
    ssize_t retval = 0;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // TCP socket
    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    if (inet_pton(AF_INET, host, &serverAddr.sin_addr) <= 0) {
        printf("inet_pton failed!\r\n");
        sockfd = -1;
    }
    if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        printf("connect failed!\r\n");
        sockfd = -1;
    }
    printf("connect to server %s success!\r\n", host);
    retval = send(sockfd, request, sizeof(request), 0);
    if (retval < 0) {
        printf("send request failed!\r\n");
        sockfd = -1;
    }
    printf("send request{%s} %ld to server done!\r\n", request, retval);
}
void SEND_aduio(const char* host, unsigned short port)
{
    ssize_t all_audio;
    ssize_t retval = 0;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    if (inet_pton(AF_INET, host, &serverAddr.sin_addr) <= 0) {
        printf("inet_pton failed!\r\n");
        sockfd = -1;
    }
    if (connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
        printf("connect failed!\r\n");
        sockfd = -1;
    }
    printf("connect to server %s success!\r\n", host);
    for (all_audio = 0; all_audio < Audio_buff_Num; all_audio++) {
    retval = send(sockfd, get_buff1[all_audio], Audio_buff_data_Lenth, 0);
    osDelay(Delay_Lenth);
    if (retval < 0) {
        printf("send request failed!\r\n");
        printf("do_cleanup...\r\n");
        sockfd = -1;
    }
    }
    retval = send(sockfd, "js", Send_Lenth, 0);
    osDelay(Delay_Lenth);
    printf("send request{%s} %ld to server done!\r\n", request, retval);
}
int WifiConnect(char *ssid, char *pwd)
{
    WifiErrorCode geterrCode;
    WifiEvent eventListener = {
        .OnWifiConnectionChanged = OnWifiConnectionChanged,
        .OnWifiScanStateChanged = OnWifiScanStateChanged
    };
    WifiDeviceConfig apConfig = {};
    int netId = -1;
    osDelay(Delay_Lenth);
    geterrCode = RegisterWifiEvent(&eventListener);
    printf("RegisterWifiEvent: %d\r\n", geterrCode);
    strcpy(apConfig.ssid, ssid);
    strcpy(apConfig.preSharedKey, pwd);
    apConfig.securityType = WIFI_SEC_TYPE_PSK;
    while (1) {
        geterrCode = EnableWifi();
        osDelay(Delay_Lenth);
        geterrCode = AddDeviceConfig(&apConfig, &netId);
        g_connected = 0;
        geterrCode = ConnectTo(netId);
        if (geterrCode != 0) {
            return -1;
        }
        printf("ConnectTo(%d): %d\r\n", netId, geterrCode);
        while (!g_connected) {
            osDelay(Delay_Lenth);
        }
        printf("g_connected: %d\r\n", g_connected);
        if_get_wifi_flag = 1;
        WR_WIFI_SSID(ssid);
        WR_WIFI_PWSD(pwd);
        // 联网业务开始
        struct netif* iface = netifapi_netif_find("wlan0");
        if (iface) {
            err_t ret = netifapi_dhcp_start(iface);
            printf("netifapi_dhcp_start: %d\r\n", ret);
            ret = netifapi_netif_common(iface, dhcp_clients_info_show, NULL);
            printf("netifapi_netif_common: %d\r\n", ret);
        }
        while (1) {
            osDelay(Delay_Lenth);
            if (audio_flag == 1) {
                audio_flag = 0;
                TcpClientTest(MY_ip, my_port);
            }
            if (audio_flag == Audio_flag) {
                audio_flag = 0;
                SEND_aduio(MY_ip, my_port);
            }
        }
    }
}